from abc import ABC, abstractmethod

__all__ = ["Processor"]


class Processor[U, V](ABC):
    """
    A processor.

    A processor is an object that takes in a stage and returns a new stage. This is the core abstraction of the project.
    Any transformation that can be performed on a stage can be implemented as a processor.
    """

    @abstractmethod
    def process(self, stage: U) -> V:
        """
        Process the stage.

        Args:
            stage: The stage to process.

        Returns:
            The processed stage.
        """
        raise NotImplementedError()

    def __call__(self, stage: U) -> V:
        return self.process(stage)
